package com.oauth2.demo.utils;

import java.net.URI;
import java.time.LocalDateTime;

import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpUtil;


import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.oauth2.demo.model.WeixinQrCode;
import com.oauth2.demo.model.WxUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author https://www.wdbyte.com
 */
@Slf4j
@Component
public class WeixinApiUtil {

    @Value("${appId}")
    public String appId;

    @Value("${secret}")
    public String appSecret;

    private static String QR_CODE_URL_PREFIX = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=";

    private static String ACCESS_TOKEN = null;
    private static LocalDateTime ACCESS_TOKEN_EXPIRE_TIME = null;
    /**
     * 二维码 Ticket 过期时间
     */
    private static int QR_CODE_TICKET_TIMEOUT = 10 * 60;

    /**
     * 获取 access token
     *
     * @return
     */
    public synchronized String getAccessToken() {
        if (ACCESS_TOKEN != null && ACCESS_TOKEN_EXPIRE_TIME.isAfter(LocalDateTime.now())) {
            return ACCESS_TOKEN;
        }
        String api = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret="
                + appSecret;
        String result = HttpUtil.get(api);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        ACCESS_TOKEN = jsonObject.getStr("access_token");
        ACCESS_TOKEN_EXPIRE_TIME = LocalDateTime.now().plusSeconds(jsonObject.getLong("expires_in") - 10);
        return ACCESS_TOKEN;
    }

    // https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    public synchronized JSONObject getAccessToken2(String code) {

        String api = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret="
                + appSecret + "&code=" + code + "&grant_type=authorization_code";
        String result = HttpUtil.get(api);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        String accessToken = jsonObject.getStr("access_token");
        return jsonObject;
    }

    public WxUser getUserInfo(String code) {

        JSONObject jsonObject = getAccessToken2(code);
        String api = "https://api.weixin.qq.com/sns/userinfo?access_token=" + jsonObject.getStr("access_token") + "&openid="
                + jsonObject.getStr("openid") + "&lang=zh_CN";
        String result = HttpUtil.get(api);
        WxUser wxUser = JSON.parseObject(result, WxUser.class);
//        WxUser wxUser = JSONUtil.tob(result, WxUser.class);
        return wxUser;
    }


    /**
     * 获取二维码 Ticket
     *
     * https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html
     *
     * @return
     */
    public WeixinQrCode getQrCode(String uuid) {
        String api = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + getAccessToken();
        String jsonBody = String.format("{\n"
                + "  \"expire_seconds\": %d,\n"
                + "  \"action_name\": \"QR_STR_SCENE\",\n"
                + "  \"action_info\": {\n"
                + "    \"scene\": {\n"
                + "      \"scene_str\": \"%s\"\n"
                + "    }\n"
                + "  }\n"
                + "}", QR_CODE_TICKET_TIMEOUT, uuid);
        System.out.println(jsonBody);
        String result = HttpUtil.post(api, jsonBody);
        log.info("get qr code params:{}", jsonBody);
        log.info("get qr code result:{}", result);
        WeixinQrCode weixinQrCode = JSONUtil.toBean(result, WeixinQrCode.class);
        weixinQrCode.setQrCodeUrl(QR_CODE_URL_PREFIX + URI.create(weixinQrCode.getTicket()).toASCIIString());
        return weixinQrCode;
    }
}
